package com.xjrsoft.third;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.xjrsoft.common.Enum.EnabledMarkEnum;
import com.xjrsoft.core.tool.utils.CollectionUtil;
import com.xjrsoft.core.tool.utils.StringUtil;
import com.xjrsoft.module.customerTwo.EMP.electricity_cost_records_day.service.ITElectricityCostRecordsDayService;
import com.xjrsoft.module.customerTwo.EMP.electricity_cost_records_month.service.ITElectricityCostRecordsMonthService;
import com.xjrsoft.module.customerTwo.EMP.price_setting.service.ITPriceSettingService;
import com.xjrsoft.module.customerTwo.EMP.t_electric_meter_sum.service.ITElectricMeterSumService;
import com.xjrsoft.module.customerTwo.EMP.t_water_cost_records_day.service.ITWaterCostRecordsDayService;
import com.xjrsoft.module.customerTwo.EMP.t_water_cost_records_month.service.ITWaterCostRecordsMonthService;
import com.xjrsoft.module.customerTwo.EMP.t_water_meter.entity.TWaterMeter;
import com.xjrsoft.module.customerTwo.EMP.t_water_meter.service.ITWaterMeterService;
import com.xjrsoft.module.oa.entity.XjrOaNews;
import com.xjrsoft.module.oa.service.IXjrOaNewsService;
import com.xjrsoft.module.oa.utils.SendMessageUtil;
import com.xjrsoft.third.adapter.LocalDateTimeAdapter;
import com.xjrsoft.third.entity.HttpSendConstant;
import com.xjrsoft.third.entity.HttpSendParams;
import com.xjrsoft.third.entity.WaterMeterResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class WaterMeterApi {
    //冷水表
    @Autowired
    private ITWaterMeterService waterMeterService;
    //恒林水表接口url
    private final String URL = "http://meter-api.ucn.plus/";
    //恒林水表接口鉴权 Authorization
    private final String AUTHORIZATION = "Basic b3BlbmNsaWVudDpvcGVuY2xpZW50";
    //恒林水表 openId参数
    private final String OPENID = "76f2333084164eddbc7f7a2a855fb4a3";

    @Autowired
    private IXjrOaNewsService newsService;
    //电量汇总
    @Autowired
    private  ITElectricMeterSumService itElectricMeterSumService;
    //每日电量记录
    @Autowired
    private  ITElectricityCostRecordsDayService itElectricityCostRecordsDayService;
    //电费单价设置
    @Autowired
    private  ITPriceSettingService itPriceSettingService;
    //每月电量记录
    @Autowired
    private ITElectricityCostRecordsMonthService tElectricityCostRecordsMonthService;

    @Autowired
    private ITWaterCostRecordsMonthService tWaterCostRecordsMonthService;
    //每日水费记录
    @Autowired
    private ITWaterCostRecordsDayService itWaterCostRecordsDayService;


    /**
     * 用户鉴权
     * @return
     */
    private String getToken(){
        //组装请求参数
        HttpSendParams httpSendParams = new HttpSendParams(URL+"auth/oauth/token?grant_type=client_credentials&scope=open", HttpSendConstant.POST,HttpSendConstant.CONTENT_TYPE_POST,AUTHORIZATION);
        //调用用户鉴权接口
        Response response = HttpClientUtils.send(httpSendParams);
        if(null != response){
            if(response.code() != 200){
                log.info("WaterMeterApi getToken failed：{} {}",response.code(),response.message());
                return "";
            }
            String msg = "";
            try {
                msg = response.body().string();
            } catch (IOException e) {
                log.error("WaterMeterApi getToken error",e);
            }
            if(StringUtil.isNoneBlank(msg)){
                JSONObject jsonObject = new JSONObject(msg);
                return jsonObject.get("access_token").toString();
            }
        }
        return "";
    }

    /**
     * 获取水表数据
     * @param token 用户鉴权获取到的token
     * @param openId 调用第三方接口公司参数
     * @return
     */
    private List<TWaterMeter> getWaterMeterList(String token,String openId){
        String url = URL +"open/openapi/read/info/page/"+openId;
        int current = 1;
        int size = 100;
        int pages = 1;  //总页数
        List<TWaterMeter> list = new ArrayList<>();
        do{
            String param = "?current="+current+"&size="+size;
            //组装请求参数
            HttpSendParams httpSendParams = new HttpSendParams(url+param, HttpSendConstant.GET,HttpSendConstant.CONTENT_TYPE_FROM,"Bearer "+token);
            Response response = HttpClientUtils.send(httpSendParams);
            if(null != response){
                if(response.code() != 200){
                    log.info("WaterMeterApi getWaterMeterList failed：url[{}] code[{}] message[{}]",url+param,response.code(),response.message());
                    return null;
                }
                String msg = "";
                try {
                    msg = response.body().string();
                } catch (IOException e) {
                    log.error("WaterMeterApi getToken error",e);
                }
                if(StringUtil.isNoneBlank(msg)){

                    Gson gson = new GsonBuilder()
                            .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
                            .create();
                    WaterMeterResponse waterMeterResponse = gson.fromJson(msg,WaterMeterResponse.class);
                    if(null != waterMeterResponse.getData()){
                        pages = waterMeterResponse.getData().getPages();
                        current++;
                        list.addAll(waterMeterResponse.getData().getRecords());
                    }
                }
            }
        }while (current <= pages);
        return list;
    }

    //3.添加定时任务(每天凌晨0:01执行)
//    @Scheduled(cron = "10 10 0 ? * *")
    //或直接指定时间间隔，例如：一小时
    @Scheduled(fixedRate=3600000)
    private void configureTasks(){
        //用户鉴权
        String token = getToken();
        if(StringUtil.isBlank(token)){
            return;
        }
        //获取水表数据
        List<TWaterMeter> list = getWaterMeterList(token,OPENID);
        if(CollectionUtil.isEmpty(list)){
            log.info("WaterMeterApi no data!");
        }
        if(waterMeterService.updateOrInsertBatch(list)>0){
            waterMeterService.alterAutoIncrement();
            log.info("WaterMeterApi success!tatal {}",list.size());
        }
    }

    //电表数据检查，每天早晨8点执行
    @Scheduled(cron = "0 0 8 ? * *")
//    @Scheduled(fixedRate=3600000)
    private void electricMeterDateInspect(){
        List<Map> list = waterMeterService.getWaringData();
        if(CollectionUtil.isNotEmpty(list)){
            try{
                String content ="<p>";
                for(Map one : list){
                    content+=one.get("room_number")+"["+one.get("energy_meter_number")+"] ";
                }
                content+=" 电表今日无数据上传，请检查是否有异常</p>";
                XjrOaNews oaNews = new XjrOaNews();
                oaNews.setNewsId(IdWorker.get32UUID());
                oaNews.setCategoryId("内部公告");
                oaNews.setFullHead("电表数据上传异常提醒");
                oaNews.setTypeId(2);
                oaNews.setReleaseTime(LocalDateTime.now());
                oaNews.setEnabledMark(EnabledMarkEnum.ENABLED.getCode());
                oaNews.setNewsContent(content);
                oaNews.setCreateUserId("dd5d4xBrDO");
                oaNews.setCreateUserName("超级管理员");
                oaNews.setCreateDate(LocalDateTime.now());
                //新增一条消息内容
                newsService.save(oaNews);
                //发送消息
                boolean flag = SendMessageUtil.sendNewsMessage(oaNews,10,"dd5d4xBrDO");
                log.info("electricMeterDateInspect===============>消息发送{}",flag?"成功":"失败");
            }catch (Exception e){
                log.error("electricMeterDateInspect===============>",e);
            }
        }else{
            log.info("electricMeterDateInspect===============>无电表数据异常");
        }
    }

    /**
     * 每月一号凌晨4点自动新增电表月度数据
     */
    @Scheduled(cron = "0 0 4 1 * ?")
    private void addElectricMeterData(){
        LocalDate yesterday = LocalDate.now().minusDays(1);
        int year = yesterday.getYear();
        int month = yesterday.getMonthValue();
        String start = month <= 9 ? year+"-0"+month+"-01" : year+"-"+month+"-01";
        //获取电费单价
        BigDecimal electricityPrice = itPriceSettingService.getElectricityPrice();
        month +=1;
        //处理起始日期
        String end = "";
        if(month == 13){
            year+=1;
            end = year+"-01-01";
        }else {
            end = month <= 9 ? year+"-0"+month+"-01" : year+"-"+month+"-01";
        }
        //处理电费汇总
        boolean flag = itElectricMeterSumService.dealData(start,end);
        if(!flag){
            log.error("electricity_cost_records_month 处理电费汇总失败，日期范围 {}-{}",start,end);
        }
        //处理每日电费记录
        flag = itElectricityCostRecordsDayService.dealElectricityCostRecordsDay(start,end,electricityPrice);
        if(!flag){
            log.error("electricity_cost_records_month 处理每日电费记录失败，日期范围 {}-{}",start,end);
        }
        //处理月电费记录
        int count = tElectricityCostRecordsMonthService.insertDataByDay(start,end);
        log.info("electricity_cost_records_month 费用结算完毕，共处理{}条记录",count);
    }

    /**
     * 每月一号凌晨5点自动新增水表月度数据
     */
    @Scheduled(cron = "0 0 5 1 * ?")
    private void addWaterMeterData(){
        LocalDate yesterday = LocalDate.now().minusDays(1);
        int year = yesterday.getYear();
        int month = yesterday.getMonthValue();
        String start = month <= 9 ? year+"-0"+month+"-01" : year+"-"+month+"-01";
        month +=1;
        //处理起始日期
        String end = "";
        if(month == 13){
            year+=1;
            end = year+"-01-01";
        }else {
            end = month <= 9 ? year+"-0"+month+"-01" : year+"-"+month+"-01";
        }
        //删除历史数据
        tWaterCostRecordsMonthService.deleteWaterDate(start,end);
        tWaterCostRecordsMonthService.deleteWaterCostRecordsDay(start,end);
        tWaterCostRecordsMonthService.deleteWaterCostRecordsMonth(year+"",yesterday.getMonthValue()+"");
        //数据写入中转表(原始数据变成根据房间号、日期汇总每天最小用水量(当天最小-昨天最小=昨天整天用水量))
        int count = tWaterCostRecordsMonthService.addTransitionData(start,end);
        //中转表数据汇总（从中转表最小用水量计算当天用水量）
        if(count == 0){
            log.warn("TWaterCostRecordsMonthController addTransitionData no data. date {}-{}",start,end);
            return;
        }
        count = tWaterCostRecordsMonthService.addSumData(start,end);
        if(count == 0){
            log.warn("TWaterCostRecordsMonthController addSumData no data. date {}-{}",start,end);
        }
        //取冷水费单价、热水费单价
        BigDecimal coldWaterPrice = itPriceSettingService.getColdWaterPrice();
        BigDecimal heatWaterPrice = itPriceSettingService.getHeatWaterPrice();
        //计算每人每天用水量、费用
        count = itWaterCostRecordsDayService.addDayRecordsData(start,end,coldWaterPrice,heatWaterPrice);
        if(count == 0){
            log.warn("TWaterCostRecordsMonthController addDayRecordsData no data. date {}-{}",start,end);
        }else {
            log.info("TWaterCostRecordsMonthController save day data success. total {}",count);
        }
        //查询需要分摊水费的数据
        List<String> ids = itWaterCostRecordsDayService.selectProportionIdList(start,end);
        if(CollectionUtil.isNotEmpty(ids)){
            itWaterCostRecordsDayService.updateProportionData(ids);
        }
        //处理月度水费记录
        count = tWaterCostRecordsMonthService.insertDataByDay(start,end);
        if(count == 0){
            log.warn("TWaterCostRecordsMonthController insertDataByDay no data. date {}-{}",start,end);
        }else{
            log.info("TWaterCostRecordsMonthController save month data success. total {}",count);
        }
    }
}
